import * as THREE from '../../build/three.module.js';
import {
  OrbitControls
} from '../../jsm/controls/OrbitControls.js'

let scene = new THREE.Scene();

let geometry = new THREE.BufferGeometry();

/**
 * 全部点坐标都插入，但我们发现，每个相邻三角面都会有两个顶点重复，因此可以使用顶点索引来优化缓冲区数据
 */
// let psi = new Float32Array([
//   0, 0, 0,
//   80, 0, 0,
//   80, 80, 0,

//   0, 0, 0,
//   80, 80, 0,
//   0, 80, 0
// ]);
// geometry.attributes.position = new THREE.BufferAttribute(psi, 3);
// let normals = new Float32Array([
//   0, 0, 1,
//   0, 0, 1,
//   0, 0, 1,

//   0, 0, 1,
//   0, 0, 1,
//   0, 0, 1,
// ]);
// geometry.attributes.normal = new THREE.BufferAttribute(normals, 3);

/**
 * 下面是通过顶点索引优化后的写法
 */
let psi = new Float32Array([
  0, 0, 0,
  80, 0, 0,
  80, 80, 0,

  0, 80, 0 // 只需新增第二个三角面中没有重复的顶点
]);
geometry.attributes.position = new THREE.BufferAttribute(psi, 3);
let normals = new Float32Array([
  0, 0, 1,
  0, 0, 1,
  0, 0, 1,
  0, 0, 1, // 法线同理
]);
geometry.attributes.normal = new THREE.BufferAttribute(normals, 3);
// 新增索引缓冲区
let indexs = new Uint16Array([
  0, 1, 2, // 相当于是顶点数据下标，直接对应该顶点的三维坐标xyz、法向量坐标xyz，包括颜色缓冲区中rgb数值
  0, 2, 3
  // 此处 顶点0，顶点1，顶点2 构成一个三角面，顶点0 2 3构成一个三角面
]);
geometry.index = new THREE.BufferAttribute(indexs, 1);

let meshMaterial = new THREE.MeshLambertMaterial({
  color: 0x0000ff,
  side: THREE.DoubleSide
});
let mesh = new THREE.Mesh(geometry, meshMaterial);
scene.add(mesh);

let lineMaterial = new THREE.LineBasicMaterial({
  color: 0x000000,
  linewidth: 2
});
let line = new THREE.Line(geometry, lineMaterial);
scene.add(line);

let ambL = new THREE.AmbientLight(0x444444);
scene.add(ambL);

let pointL = new THREE.PointLight(0xffffff);
pointL.position.set(-100, 0, 200);
scene.add(pointL);

let axesH = new THREE.AxesHelper(200);
scene.add(axesH);

let width = window.innerWidth,
    height = window.innerHeight,
    k = width / height,
    s = 200,
    camera = new THREE.OrthographicCamera(-s * k, s * k, s, -s, 1, 1000);
camera.position.set(400, 400, 400);
camera.lookAt(scene.position);

let renderer = new THREE.WebGLRenderer();
renderer.setSize(width, height);
renderer.setClearColor(0xdddddd, 1);
document.body.appendChild(renderer.domElement);

new OrbitControls(camera, renderer.domElement);

function render () {
  requestAnimationFrame(render);
  renderer.render(scene, camera);
}
render()